package com.shihc.mina.start.server;

import com.shihc.mina.start.filter.MyFilter1;
import com.shihc.mina.start.filter.MyFilter2;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.concurrent.Executors;

/**
 * Created by shihc on 2016/1/18.
 */
public class MinaTimeServer {

    private static final int PORT = 9123;

    public static void main( String[] args ) throws IOException {
        NioSocketAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast( "filter1", new MyFilter1() );
        acceptor.getFilterChain().addLast( "filter2", new MyFilter2() );

        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName("UTF-8"))));
        //acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));

        acceptor.setHandler(new TimeServerHandler());

        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        //SocketSessionConfig继承自IoSessionConfig
        acceptor.getSessionConfig().setTcpNoDelay(true);

        acceptor.bind(new InetSocketAddress(PORT));
    }

    public static class TimeServerHandler extends IoHandlerAdapter {
        @Override
        public void exceptionCaught( IoSession session, Throwable cause ) throws Exception {
            cause.printStackTrace();
        }

        @Override
        public void messageReceived( IoSession session, Object message ) throws Exception {

            Thread.sleep(2000);
            //不添加ExecutorFilter时输出：Handler处理时线程：NioProcessor-2
            // 每隔2秒输出一次消息

            //添加ExecutorFilter时输出：Handler处理时线程：pool-3-thread-1、Handler处理时线程：pool-3-thread-3等
            //五条消息几乎同时输出
            System.out.println("Handler处理时线程：" + Thread.currentThread().getName());
            String str = message.toString();
            if( str.trim().equalsIgnoreCase("quit") ) {
                session.close(true);
                return;
            }

            Date date = new Date();
            session.write( date.toString() );
            System.out.println("Message written...");
        }

        @Override
        public void sessionIdle( IoSession session, IdleStatus status ) throws Exception {
            System.out.println( "IDLE " + session.getIdleCount( status ));
        }
    }
}
